/*
 * @Author: your name
 * @Date: 2022-01-26 18:47:05
 * @LastEditTime: 2022-01-26 18:54:49
 * @LastEditors: your name
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: /goose-server/src/main.ts
 */
import { NestFactory } from "@nestjs/core";
import { Logger } from "@nestjs/common";
import { NestExpressApplication } from "@nestjs/platform-express";
import { AppModule } from "./app.module";
import { ConfigModule } from "./modules/config/config.module";
import { ConfigService } from "./modules/config/services/config.service";
import { ConfigProvider } from "./modules/config/constants/config.constant";
import { ValidationPipe } from "./pipes/validation.pipe";
import { generateSwagger } from "./service";
import * as helmet from "helmet";
import * as rateLimit from "express-rate-limit";
import * as bodyParser from "body-parser";
import { RequestContextMiddleware } from "./middlewares/request-context.middleware";
import { join } from "path";
require("body-parser-xml")(bodyParser);

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  const configService = app
    .select(ConfigModule)
    .get<ConfigService>(ConfigProvider);

  // 静态资源目录
  app.useStaticAssets(join(__dirname, "..", "public"), { prefix: "/public/" });

  //https://bleepcoder.com/swagger/728271787/it-changing-protocol-from-http-to-https-on-vps-and-show
  if (configService.common.enableSwagger) generateSwagger(app);

  //允许跨域请求
  app.enableCors();

  //使用helmet进行安全防护，文档详见：https://helmetjs.github.io/docs/
  app.use(helmet());

  // 简单抵御DDoS攻击，文档地址：https://www.npmjs.com/package/express-rate-limit
  app.use(
    rateLimit({
      windowMs: 15 * 60 * 1000, // 15 minutes
      max: 1000, // limit each IP to 1000 requests per windowMs
    })
  );

  //设置json，url和xml数据包大小上限
  app.use(bodyParser.json({ limit: "50mb" }));
  app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
  app.use(
    bodyParser["xml"]({
      limit: "1MB", // Reject payload bigger than 1 MB
      xmlParseOptions: {
        normalize: true, // Trim whitespace inside text nodes
        normalizeTags: true, // Transform tags to lowercase
        explicitArray: false, // Only put nodes in array if >1
      },
    })
  );

  //上下文中间件，用于获取用户
  app.use(RequestContextMiddleware);

  // 全局使用管道(数据校验)
  app.useGlobalPipes(new ValidationPipe());

  // 允许关闭hooks
  app.enableShutdownHooks();

  await app.listen(configService.common.port);

  Logger.log(`服务已经启动:${await app.getUrl()}`);
}
bootstrap();
